@file:Suppress("UNCHECKED_CAST")

package hos.thread.lifecycle

import android.annotation.SuppressLint
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import hos.thread.RunnableJob
import hos.thread.ThreadOption


/**
 * <p>Title: CallBackgroundLife </p>
 * <p>Description: 感知生命周期 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @date : 2023/7/28 11:41
 * @version : 1.0
 */
@SuppressLint("RestrictedApi")
open class LifecycleRunJob<T> protected constructor(
    override val onBackground: (RunnableJob<T>.() -> T),
) : RunnableJob<T>(onBackground) {

    companion object {

        @JvmStatic
        @JvmOverloads
        fun <T> runLifecycle(
            lifecycleOwner: LifecycleOwner, job: ThreadOption.Job = ThreadOption.Job.ON,
            onBackground: (RunnableJob<T>.() -> T),
        ) = LifecycleRunJob<T>(onBackground).start(lifecycleOwner, job)

        @JvmStatic
        fun <T> getLifecycle(
            onBackground: (RunnableJob<T>.() -> T),
        ) = LifecycleRunJob<T>(onBackground)

    }

    protected var lifecycleOwner: LifecycleOwner? = null

    protected val lifecycleObserver by lazy {
        object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    // 页面销毁的时候，取消执行
                    lifecycleOwner?.lifecycle?.removeObserver(this)
                    onDestroy()
                }
            }
        }
    }

    override fun runUI(run: () -> Unit) {
        lifecycleOwner?.runLifecycleUI {
            run.invoke()
        }
    }

    @Deprecated(
        message = "please use start(lifecycleOwner: LifecycleOwner, job: ThreadOption.Job)",
        replaceWith = ReplaceWith(
            "start(lifecycleOwner: LifecycleOwner, job: ThreadOption.Job)",
            "hos.thread.lifecycle.LifecycleRunJob"
        )
    )
    override fun start(job: ThreadOption.Job): RunnableJob<T> {
        return super.start(job)
    }

    @JvmOverloads
    open fun start(
        lifecycleOwner: LifecycleOwner,
        job: ThreadOption.Job = ThreadOption.Job.ON,
    ): RunnableJob<T> {
        if (lifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            // 当前页面已经关闭
            return this
        }
        this.lifecycleOwner = lifecycleOwner
        lifecycleOwner.runLifecycleUI {
            lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
        }
        return super.start(job)
    }

    override fun onDestroy() {
        super.onDestroy()
        lifecycleOwner = null
    }

}